package epidemic

import (
	"fmt"
	"gitee.com/baal1990/epidemic/global"
	"gitee.com/baal1990/epidemic/model/epidemic"
	epidemicReq "gitee.com/baal1990/epidemic/model/epidemic/request"
	"strings"
	"time"
)

type DataStatistics struct {
}

type OverviewByDepartment map[string]*epidemic.AttendanceData

func (d DataStatistics) InPositionUserList(req epidemicReq.EpidemicUserSearch) (total int64, list []epidemic.EpidemicUser, err error) {
	limit := req.PageSize
	offset := req.PageSize * (req.Page - 1)
	db := global.GVA_DB.Table("epidemic_related_staff").
		Joins("right join epidemic_user using (mobile)").
		Where("epidemic_related_staff.name is null and epidemic_user.name is not null and epidemic_user.name !=''")
	// 如果有条件搜索 下方会自动创建搜索语句
	if req.EpidemicUserSearch.Name != "" {
		db = db.Where(" AES_DECRYPT(FROM_BASE64(`name`), '"+global.ENCRYPTKEY_AES+"') like ?", "%"+req.Name+"%")
	}
	if req.EpidemicUserSearch.Department != "" {
		db = db.Where("department = ?", req.Department)
	}
	if req.EpidemicUserSearch.Location != "" {
		db = db.Where("location = ?", req.Location)
	}
	if req.EpidemicUserSearch.Status != "" {
		db = db.Where("status = ?", req.Status)
	}
	if req.EpidemicUserSearch.Role != "" {
		db = db.Where("role = ?", req.Role)
	}
	if req.EpidemicUserSearch.Label != "" {
		labelSlice := strings.Split(req.EpidemicUserSearch.Label, ",")
		for i, e := range labelSlice {
			if i == 0 {
				db = db.Where("label like ?", "%"+e+"%")
			} else {
				db = db.Or("label like ?", "%"+e+"%")
			}
		}
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Limit(limit).
		Offset(offset).
		Order("id desc").
		Select("epidemic_user.*").
		Find(&list).Error
	if err != nil {
		return
	}
	err = encryptUserInfoInList(list)
	return
}

// AttendanceOverview 出勤表
func (d DataStatistics) AttendanceOverview() (result epidemic.AttendanceOverview, err error) {
	overview := make(OverviewByDepartment)
	if err = totalNumByDepartment(overview); err != nil {
		return
	}
	if err = totalNumMiddleByDepartment(overview); err != nil {
		return
	}
	if err = inPositionNumByDepartment(overview); err != nil {
		return
	}
	if err = totalNum(overview, true); err != nil {
		return
	}
	if err = totalNumMiddle(overview, true); err != nil {
		return
	}
	if err = inPositionNum(overview, true); err != nil {
		return
	}
	if err = totalNum(overview, false); err != nil {
		return
	}
	if err = totalNumMiddle(overview, false); err != nil {
		return
	}
	if err = inPositionNum(overview, false); err != nil {
		return
	}
	dataHighManage := epidemic.AttendanceData{}
	for k, v := range overview {
		if k == "dalian" {
			result.Dalian.Total = v.TotalRegular + v.TotalOutsourced
			result.Dalian.InPositionTotal = v.InPositionRegular + v.InPositionOutsourced
			result.Dalian.HomeTotal = v.HomePositive + v.HomeOthers
			percent := float64(result.Dalian.InPositionTotal) / float64(result.Dalian.Total) * 100
			v.AttendancePercentage = fmt.Sprintf("%.2f%%", percent)
			result.Dalian.Data = *v

		} else if k == "all" {
			result.All.Total = v.TotalRegular + v.TotalOutsourced
			result.All.InPositionTotal = v.InPositionRegular + v.InPositionOutsourced
			result.All.HomeTotal = v.HomePositive + v.HomeOthers
			percent := float64(result.All.InPositionTotal) / float64(result.All.Total) * 100
			v.AttendancePercentage = fmt.Sprintf("%.2f%%", percent)
			result.All.Data = *v
		} else {
			percent := float64(v.InPositionOutsourced+v.InPositionRegular) / float64(v.TotalRegular+v.TotalOutsourced) * 100
			v.AttendancePercentage = fmt.Sprintf("%.2f%%", percent)
			v.Department = k
			if k == global.DEPARTMENT_HIGH_MANAGER {
				dataHighManage = *v
			} else {
				result.Data = append(result.Data, *v)
			}
		}
	}
	// 高管排最前面
	tmp := result.Data
	result.Data = append([]epidemic.AttendanceData{}, dataHighManage)
	result.Data = append(result.Data, tmp...)
	return
}

// ManageInPosition 中高层到岗
func (d DataStatistics) ManageInPosition() (result epidemic.ManagerOverview, err error) {
	var users []epidemic.ManagerInfo
	err = global.GVA_DB.Table("epidemic_related_staff").
		Select("AES_DECRYPT(FROM_BASE64(epidemic_user.name), '"+global.ENCRYPTKEY_AES+"') as name, epidemic_user.location, isolation_type, epidemic_user.department,label").
		Joins("right join epidemic_user using (mobile)").
		Where("(label like ? or label like ?) and epidemic_related_staff.name is null", "%"+global.LABEL_MIDDLE+"%", "%"+global.LABEL_HIGH+"%").
		Find(&users).Error
	if err != nil {
		return
	}
	nowDate := time.Now().Format("1月2日")
	middleMap := make(map[string]epidemic.ManagerInfo)
	for _, e := range users {
		e.Date = nowDate
		if strings.Contains(e.Label, global.LABEL_HIGH) {
			result.High = append(result.High, e)
		} else {
			value, ok := middleMap[e.Department]
			if ok {
				value.Count += 1
				if strings.Contains(e.Label, global.LABLE_DEPARTMENT_LEADER) {
					value.Name = e.Name + "," + value.Name // 部门负责人排前面
				} else {
					value.Name += "," + e.Name
				}
				middleMap[e.Department] = value
			} else {
				e.Count = 1
				middleMap[e.Department] = e
			}
		}
	}
	for _, v := range middleMap {
		result.Middle = append(result.Middle, v)
	}
	return
}

// ManageHome 中高层居家
func (d DataStatistics) ManageHome() (result epidemic.ManagerOverview, err error) {
	var users []epidemic.ManagerInfo
	err = global.GVA_DB.Table("epidemic_related_staff").
		Select("AES_DECRYPT(FROM_BASE64(epidemic_user.name), '"+global.ENCRYPTKEY_AES+"') as name, epidemic_user.location, isolation_type, epidemic_user.department,label").
		Joins("inner join epidemic_user using (mobile)").
		Where("label like ? or label like ?", "%"+global.LABEL_MIDDLE+"%", "%"+global.LABEL_HIGH+"%").
		Find(&users).Error
	if err != nil {
		return
	}
	nowDate := time.Now().Format("1月2日")
	for _, e := range users {
		e.Date = nowDate
		if strings.Contains(e.Label, global.LABEL_HIGH) {
			result.High = append(result.High, e)
		} else {
			result.Middle = append(result.Middle, e)
		}
	}
	return
}

// 员工总数
func totalNumByDepartment(overview OverviewByDepartment) (err error) {
	var num []epidemic.TotalNum
	db := global.GVA_DB.Table("epidemic_user").
		Select("department, organization, count(*) as total").
		Group("department, organization").
		Having("department != ''").
		Order("department").
		Find(&num)
	if err = db.Error; err != nil {
		return
	}
	for _, e := range num {
		data, ok := overview[e.Department]
		if !ok {
			data = &epidemic.AttendanceData{}
			overview[e.Department] = data
		}
		if e.Organization == global.ORGANIZATION_OUTSOURCED {
			data.TotalOutsourced += e.Total
			data.InPositionOutsourced = data.TotalOutsourced // 临时记录，后续做减
		} else {
			data.TotalRegular += e.Total
			data.InPositionRegular = data.TotalRegular // 临时记录，后续做减
		}
	}
	return
}

// 员工总数
func totalNumMiddleByDepartment(overview OverviewByDepartment) (err error) {
	var num []epidemic.TotalNum
	db := global.GVA_DB.Table("epidemic_user").
		Select("department, organization, count(*) as total").
		Where("label like ?", "%"+global.LABEL_MIDDLE+"%").
		Group("department, organization").
		Having("department != ''").
		Order("department").
		Find(&num)
	if err = db.Error; err != nil {
		return
	}
	for _, e := range num {
		data, ok := overview[e.Department]
		if !ok {
			data = &epidemic.AttendanceData{}
			overview[e.Department] = data
		}
		data.InPositionMiddle = e.Total // 临时记录总数
	}
	return
}

// 在岗员工数
func inPositionNumByDepartment(overview OverviewByDepartment) (err error) {
	var users []epidemic.InPosition
	db := global.GVA_DB.Table("epidemic_user").
		Select("epidemic_user.department, epidemic_user.organization, epidemic_user.label, epidemic_related_staff.isolation_type").
		Joins("inner join epidemic_related_staff on epidemic_related_staff.mobile = epidemic_user.mobile").
		Find(&users)
	if err = db.Error; err != nil {
		return
	}
	for _, e := range users {
		data, ok := overview[e.Department]
		if !ok {
			data = &epidemic.AttendanceData{}
			overview[e.Department] = data
		}
		if e.Organization == global.ORGANIZATION_OUTSOURCED {
			data.InPositionOutsourced -= 1
		} else {
			data.InPositionRegular -= 1
			if e.Label == global.LABEL_MIDDLE {
				data.InPositionMiddle -= 1
			}
		}
		if e.IsolationType == global.ISOLUTION_NUCLEIC_ACID_POSITIVE ||
			e.IsolationType == global.ISOLUTION_ANTIGEN_POSITIVE {
			data.HomePositive += 1
		} else {
			data.HomeOthers += 1
		}
	}
	return
}

// 员工总数
func totalNum(overview OverviewByDepartment, dalian bool) (err error) {
	var num []epidemic.TotalNum
	db := global.GVA_DB.Table("epidemic_user").
		Select("organization, count(*) as total")
	if dalian {
		db = db.Where("department !='' and location = ?", global.LOCATION_DALIAN)
	} else {
		db = db.Where("department !=''")
	}
	db.Group("organization").
		Find(&num)
	if err = db.Error; err != nil {
		return
	}
	var key string
	if dalian {
		key = "dalian"
	} else {
		key = "all"
	}
	for _, e := range num {
		data, ok := overview[key]
		if !ok {
			data = &epidemic.AttendanceData{}
			overview[key] = data
		}
		if e.Organization == global.ORGANIZATION_OUTSOURCED {
			data.TotalOutsourced += e.Total
			data.InPositionOutsourced = data.TotalOutsourced // 临时记录，后续做减
		} else {
			data.TotalRegular += e.Total
			data.InPositionRegular = data.TotalRegular // 临时记录，后续做减
		}
	}
	return
}

// 员工总数
func totalNumMiddle(overview OverviewByDepartment, dalian bool) (err error) {
	var num int64
	db := global.GVA_DB.Table("epidemic_user").
		Where("label like ?", "%"+global.LABEL_MIDDLE+"%")

	if dalian {
		db = db.Where("location = ?", global.LOCATION_DALIAN)
	}
	db.Count(&num)
	if err = db.Error; err != nil {
		return
	}
	var key string
	if dalian {
		key = "dalian"
	} else {
		key = "all"
	}
	data, ok := overview[key]
	if !ok {
		data = &epidemic.AttendanceData{}
		overview[key] = data
	}
	data.InPositionMiddle = int(num) // 临时记录总数
	return
}

// 在岗员工数
func inPositionNum(overview OverviewByDepartment, dalian bool) (err error) {
	var users []epidemic.InPosition
	db := global.GVA_DB.Table("epidemic_user").
		Select("epidemic_user.organization, epidemic_user.label, epidemic_related_staff.isolation_type").
		Joins("inner join epidemic_related_staff on epidemic_related_staff.mobile = epidemic_user.mobile")
	if dalian {
		db = db.Where("epidemic_related_staff.location = ?", global.LOCATION_DALIAN)
	}
	db.Find(&users)
	if err = db.Error; err != nil {
		return
	}
	var key string
	if dalian {
		key = "dalian"
	} else {
		key = "all"
	}
	for _, e := range users {
		data, ok := overview[key]
		if !ok {
			data = &epidemic.AttendanceData{}
			overview[key] = data
		}
		if e.Organization == global.ORGANIZATION_OUTSOURCED {
			data.InPositionOutsourced -= 1
		} else {
			data.InPositionRegular -= 1
			if e.Label == global.LABEL_MIDDLE {
				data.InPositionMiddle -= 1
			}
		}
		if e.IsolationType == global.ISOLUTION_NUCLEIC_ACID_POSITIVE ||
			e.IsolationType == global.ISOLUTION_ANTIGEN_POSITIVE {
			data.HomePositive += 1
		} else {
			data.HomeOthers += 1
		}
	}
	return
}
